from flask import request, jsonify, g, current_app
from sqlalchemy.exc import InternalError

from apps.apis import api
from apps.core.auth import verify_json_schema, verify_token_auth
from apps.core.database import db
from apps.core.schemaall import update_ref_schema, update_meta_schema, log_sys_schema, count_subdb_year_schema
from apps.models import UpdateRef, UpdateMeta, LogSys, CountSubdbYearMeta, CountSubDbYearRef
from apps.utils.return_info import ReturnInfo


@api.route("/spark/update_ref", methods=['POST'])
@verify_json_schema(update_ref_schema)
@verify_token_auth(allowtokennull=False, namekey="SPARK_USER")
def update_ref():
    """
    引文 统计数据
    ---
    tags:
      - spark
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          id: update_ref
          properties:
            sub_db_id:
              type: string
              description: 为每个字库分配的id
              example: '00001'
            count_submit:
              type: integer
              description: 提交量.
              example: 10
            count_update:
              type: integer
              description: 更新量.
              example: 8
            count_create:
              type: integer
              description: 新增量.
              example: 8
            count_deprecated:
              type: integer
              description: 弃用量.
              example: 6
            count_delete:
              type: integer
              description: 物理删除量.
              example: 6
            count_ref:
              type: integer
              description: 更新后总量.
              example: 6
            token:
              type: string
              description: token.
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    definitions:
      ReturnInfo:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取


    consumes:
      - application/json
    produces:
      - application/json

    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfo'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"更新数据成功","data":[]}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"上传格式错误","data":[]}
      401:
        description: token 认证不通过,可能是过期
      405:
        description: 请求方式错误
    :return:
    """
    ret_obj = ReturnInfo()
    jsons = request.json
    if g.user.username != current_app.config.get("SPARK_USER"):
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "token 用户不能访问该接口"
        return jsonify(ret_obj.todict())

    sub_db_id = jsons.get("sub_db_id")
    count_submit = jsons.get("count_submit")
    count_update = jsons.get("count_update")
    count_create = jsons.get("count_create")
    count_deprecated = jsons.get("count_deprecated")
    count_delete = jsons.get("count_delete")
    count_ref = jsons.get("count_ref")

    update_ref = UpdateRef(sub_db_id=sub_db_id, count_submit=count_submit,
                           count_update=count_update, count_create=count_create,
                           count_deprecated=count_deprecated, count_delete=count_delete,
                           count_ref=count_ref)
    try:
        db.session.add(update_ref)
        db.session.commit()
    except InternalError as e:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "参数类型错误，无法插入数据库"
        ret_obj.data = {"errmsg": str(e)}
        return jsonify(ret_obj.todict())

    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "添加成功"
    return jsonify(ret_obj.todict())


@api.route("/spark/update_meta", methods=['POST'])
@verify_json_schema(update_meta_schema)
@verify_token_auth(allowtokennull=False, namekey="SPARK_USER")
def update_meta():
    """
    题录 统计数据
    ---
    tags:
      - spark
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          id: update_meta
          properties:
            sub_db_id:
              type: string
              description: 为每个字库分配的id
              example: '00001'
            count_submit:
              type: integer
              description: 提交量.
              example: 10
            count_update:
              type: integer
              description: 更新量.
              example: 8
            count_create:
              type: integer
              description: 新增量.
              example: 8
            count_deprecated:
              type: integer
              description: 弃用量.
              example: 6
            count_delete:
              type: integer
              description: 物理删除量.
              example: 6
            count_meta:
              type: integer
              description: 更新后总量.
              example: 6
            token:
              type: string
              description: token.
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    definitions:
      ReturnInfo:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取
    consumes:
      - application/json
    produces:
      - application/json
    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfo'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"更新数据成功","data":[]}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"上传格式错误","data":[]}
      401:
        description: token 认证不通过,可能是过期
      405:
        description: 请求方式错误
    :return:
    """
    ret_obj = ReturnInfo()
    jsons = request.json
    sub_db_id = jsons.get("sub_db_id")
    count_submit = jsons.get("count_submit")
    count_update = jsons.get("count_update")
    count_create = jsons.get("count_create")
    count_deprecated = jsons.get("count_deprecated")
    count_delete = jsons.get("count_delete")
    count_meta = jsons.get("count_meta")

    update_meta = UpdateMeta(sub_db_id=sub_db_id, count_submit=count_submit,
                             count_update=count_update, count_create=count_create,
                             count_deprecated=count_deprecated, count_delete=count_delete,
                             count_meta=count_meta)
    try:
        db.session.add(update_meta)
        db.session.commit()
    except InternalError as e:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "参数类型错误，无法插入数据库"
        ret_obj.data = {"errmsg": str(e)}
        return jsonify(ret_obj.todict())

    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "添加成功"
    return jsonify(ret_obj.todict())


@api.route("/spark/logsys", methods=['POST'])
@verify_json_schema(log_sys_schema)
@verify_token_auth(allowtokennull=False, namekey="SPARK_USER")
def log_sys():
    """
    spark系统日志
    ---
    tags:
      - spark
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          id: log_sys
          properties:
            log_json:
              type: object
              description: json结构的日志
            token:
              type: string
              description: token.
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    definitions:
      ReturnInfo:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取
    consumes:
      - application/json
    produces:
      - application/json

    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfo'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"更新数据成功","data":[]}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"上传格式错误","data":[]}
      401:
        description: token 认证不通过,可能是过期
      405:
        description: 请求方式错误
    :return:
    """
    ret_obj = ReturnInfo()
    jsons = request.json
    log_json = jsons.get("log_json")
    log_sys = LogSys(log_json=log_json)
    try:
        db.session.add(log_sys)
        db.session.commit()
    except InternalError as e:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "参数类型错误，无法插入数据库"
        ret_obj.data = {"errmsg": str(e)}
        return jsonify(ret_obj.todict())

    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "添加成功"
    return jsonify(ret_obj.todict())


@api.route("/spark/count_subdb_year_meta", methods=['POST'])
@verify_json_schema(count_subdb_year_schema)
@verify_token_auth(allowtokennull=False, namekey="SPARK_USER")
def count_subdb_year_meta():
    """
    所有子库统计日志
    ---
    tags:
      - spark
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          id: count_subdb_year
          properties:
            sub_db_id:
              type: string
              description: 为每个字库分配的id
              example: '00001'
            count_json:
              type: object
              description: json结构的日志
            token:
              type: string
              description: token.
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    definitions:
      ReturnInfo:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取
    consumes:
      - application/json
    produces:
      - application/json
    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfo'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"更新数据成功","data":[]}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"上传格式错误","data":[]}
      401:
        description: token 认证不通过,可能是过期
      405:
        description: 请求方式错误
    :return:
    """
    ret_obj = ReturnInfo()
    jsons = request.json
    count_json = jsons.get("count_json")
    sub_db_id = jsons.get("sub_db_id")
    count_subdb_year = CountSubdbYearMeta(count_json=count_json, sub_db_id=sub_db_id)
    try:
        db.session.add(count_subdb_year)
        db.session.commit()
    except InternalError as e:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "参数类型错误，无法插入数据库"
        ret_obj.data = {"errmsg": str(e)}
        return jsonify(ret_obj.todict())

    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "添加成功"
    return jsonify(ret_obj.todict())


@api.route("/spark/count_subdb_year_ref", methods=['POST'])
@verify_json_schema(count_subdb_year_schema)
@verify_token_auth(allowtokennull=False, namekey="SPARK_USER")
def count_subdb_year_ref():
    """
    所有子库统计日志
    ---
    tags:
      - spark
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          id: count_subdb_year
          properties:
            sub_db_id:
              type: string
              description: 为每个字库分配的id
              example: '00001'
            count_json:
              type: object
              description: json结构的日志
            token:
              type: string
              description: token.
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    definitions:
      ReturnInfo:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取
    consumes:
      - application/json
    produces:
      - application/json
    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfo'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"更新数据成功","data":[]}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"上传格式错误","data":[]}
      401:
        description: token 认证不通过,可能是过期
      405:
        description: 请求方式错误
    :return:
    """
    ret_obj = ReturnInfo()
    jsons = request.json
    count_json = jsons.get("count_json")
    sub_db_id = jsons.get("sub_db_id")
    count_subdb_year = CountSubDbYearRef(count_json=count_json, sub_db_id=sub_db_id)
    try:
        db.session.add(count_subdb_year)
        db.session.commit()
    except InternalError as e:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "参数类型错误，无法插入数据库"
        ret_obj.data = {"errmsg": str(e)}
        return jsonify(ret_obj.todict())

    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "添加成功"
    return jsonify(ret_obj.todict())
